
module I2C(
           input        iclk,
           input        rst_n,
		   	input        i_motor_en,
	        input [1:0]  i_motor,
			  input        wr_en,
			  input        rd_en,
			  input [23:0] idata,      //{设备地址,寄存器地址,寄存器值}，设备地址只要是设备地址就行，不区分读写，程序内部根据读写指令自动转换成读写对应的设备地址
			  inout        sda,
			  output       sclk,
			  output       wr_done,
			  output       rd_done,
			  output       rd_data_en,
			  output [7:0] rd_data
			  );
			  
   parameter wait_s  = 2'd0;
   parameter wr_s    = 2'd1;
   parameter rd_s    = 2'd2;
	
   parameter step1   = 6'd0;
   parameter step2   = 6'd1;
   parameter step3   = 6'd2;
   parameter step4   = 6'd3;
	parameter step5   = 6'd4;
   parameter step6   = 6'd5;
   parameter step7   = 6'd6;
   parameter step8   = 6'd7;
	parameter step9   = 6'd8;
	parameter step10  = 6'd9;
	parameter step11  = 6'd10;
	parameter step12  = 6'd11;
	parameter step13  = 6'd12;
	parameter step14  = 6'd13;
	parameter step15  = 6'd14;
	parameter step16  = 6'd15;
	parameter step17  = 6'd16;
	parameter step18  = 6'd17;
	parameter step19  = 6'd18;
	parameter step20  = 6'd19;
	parameter step21  = 6'd20;
	parameter step22  = 6'd21;
	parameter step23  = 6'd22;
	parameter step24  = 6'd23;
	parameter step25  = 6'd24;
	parameter step26  = 6'd25;
	parameter step27  = 6'd26;
	parameter step28  = 6'd27;
	parameter step29  = 6'd28;
	parameter step30  = 6'd29;

	reg        sclk_r;
	reg        iolink;       //0：输入 1:输出
	reg        sda_o;        //sda输出信号
	reg        wr_done_r;    //一次写操作完成标志
	reg        rd_done_r;    //一次读操作完成标志
	reg        rd_data_en_r; //读数据有效标志
	reg [1:0]  state;        //三个运行状态：等待读写，写I2C寄存器，读I2C寄存器
	reg [7:0]  rd_data_r;
	reg [7:0]  rd_byte;      //暂存读出的串行数据
	reg [5:0]  wr_step;      //写I2C的步骤
	reg [5:0]  rd_step;      //读I2C的步骤
	reg [1:0]  wr_cnt;       //每3个iclk构成一个完整的sclk周期，第一个时钟sclk低，sda改变，第二个时钟sclk高，sda不变，第三个时钟sclk低，sda不变
	reg [23:0] idata_r;      //寄存idata的数据，用于读或者写状态中
	reg [7:0]  byte_r;
	reg [1:0]  byte_cnt;
	
	assign sda        = i_motor_en?i_motor[1]:(iolink ? sda_o : 1'bz);
	assign sclk       = i_motor_en?i_motor[0]:sclk_r;
	assign wr_done    = wr_done_r;
	assign rd_done    = rd_done_r;
	assign rd_data_en = rd_data_en_r;
	assign rd_data    = rd_data_r;
	
  always@(posedge iclk or negedge rst_n)
  begin
      if(!rst_n)
          begin
			   sclk_r       <= 1'b1;   //在空闲状态下，I2C的时钟线是要处于高电平的（协议要求，并且协议要求只能sclk低电平时数据改变，因此起始位和结束位不会和数据混淆）
				iolink       <= 1'b1;   //默认sda是输出
			   sda_o        <= 1'b1;   //在空闲状态下，I2C的数据线是要处于高电平的
				state        <= wait_s; //初始状态为等待读/写命令状态
				rd_data_r    <= 8'd0;   //读出数据为0
				wr_step      <= step1;  
				rd_step      <= step1;
				wr_cnt       <= 2'd0;
				idata_r      <= 24'd0;   
				byte_r       <= 8'd0;
				byte_cnt     <= 2'd0;
				rd_byte      <= 8'd0;
				wr_done_r    <= 1'b0;
				rd_done_r    <= 1'b0;
				rd_data_en_r <= 1'b0;
          end
      else
          begin
            case(state)
/////////////////////////////////////////////////////////
	             wait_s:begin
	                      wr_cnt     <= 2'd0;
	                      wr_step    <= step1;
	                      rd_step    <= step1;
	                      byte_cnt   <= 2'd0;
	                      sclk_r     <= 1'b1;               //很重要，设计程序时开始没有拉高，导致进行一次读写以后就没法进行下去
	                      sda_o      <= 1'b1;               //很重要，设计程序时开始没有拉高，导致进行一次读写以后就没法进行下去
	                      if ( wr_en == 1'b1 )              //检测到写使能为高则进入写I2C数据状态
	                          begin
	                            idata_r   <= idata;
	                            byte_r    <= idata[23:16];                 // ???  无读写标志位（LSB)  ?????????????  ?????????????
	                            iolink    <= 1'b1;          //sda输出
	                            wr_done_r <= 1'b0;          //进入写状态后，写完成标志拉低
	                            state     <= wr_s;
	                          end
	                      else 
								 if(rd_en == 1'b1)                 //检测到读使能为高则进入读I2C数据状态
	                          begin
	                            idata_r      <= idata;
	                            byte_r       <= {idata[23:17],1'b0};      //读数据需要先写设备地址
	                            iolink       <= 1'b1;               
	                            rd_done_r    <= 1'b0;       //进入读状态后，读完成标志拉低
	                            rd_data_en_r <= 1'b0;       //进入读状态后，读数据使能拉低
	                            state        <= rd_s;
	                          end  
	                      else
	                          begin
	                            state   <= wait_s;
	                          end	
	                    end
/////////////////////////////////////////////////////////
	             wr_s:  begin
                         if(wr_cnt>=2'd2)                //每3个iclk跳转一个步骤，每个步骤包含了1bit数据的传输
                             begin
                               wr_cnt <= 2'd0;
                             end
                         else
                             begin
                               wr_cnt <= wr_cnt+2'd1;
                             end
                         case(wr_step)
                             step1:begin
		                               case(wr_cnt)
		                                   2'd0: sda_o   <= 1'b0;    //起始条件
		                                   2'd1: ;
		                                   2'd2: wr_step <= step2;
		                                   2'd3: ;
		                               endcase
		                             end
									  ///////////////////////////////////////////////////////////////////
                             step2:begin   //sclk连续产生8个时钟脉冲，用于sda输出8bit数据
		                               case(wr_cnt)
		                                   2'd0:begin
		                                          sda_o   <= byte_r[7];    //sda数据改变
		                                          sclk_r  <= 1'b0;         //sclk线拉低
		                                        end
		                                   2'd1:begin
		                                          sclk_r  <= 1'b1;         //sclk线拉高，sda数据不变
		                                        end
		                                   2'd2:begin
		                                          sclk_r  <= 1'b0;         //sclk线拉低
		                                          wr_step <= step3;
		                                        end
		                                   2'd3: ;
		                               endcase
		                             end
									  step3:begin
											    case(wr_cnt)
											        2'd0:begin
												            sda_o   <= byte_r[6];     //sda数据改变
												            sclk_r  <= 1'b0;          //sclk线拉低
											             end
											        2'd1:begin
												            sclk_r  <= 1'b1;          //sclk线拉高，sda数据不变
											             end
											        2'd2:begin
												            sclk_r  <= 1'b0;          //sclk线拉低
												            wr_step <= step4;
											             end
											        2'd3: ;
											    endcase
		                             end
									  step4:begin
											    case(wr_cnt)
											        2'd0:begin
												            sda_o   <= byte_r[5];     //sda数据改变
												            sclk_r  <= 1'b0;          //sclk线拉低
											             end
											        2'd1:begin
												            sclk_r  <= 1'b1;          //sclk线拉高，sda数据不变
											             end
											        2'd2:begin
											 	            sclk_r  <= 1'b0;          //sclk线拉低
												            wr_step <= step5;
											             end
											        2'd3:;
											    endcase
									        end
									  step5:begin
											    case(wr_cnt)
											        2'd0:begin
												            sda_o <= byte_r[4];       //sda数据改变
												            sclk_r     <= 1'b0;       //sclk线拉低
											             end
											        2'd1:begin
												            sclk_r     <= 1'b1;       //sclk线拉高，sda数据不变
											             end
											        2'd2:begin
												            sclk_r     <= 1'b0;       //sclk线拉低
												            wr_step <= step6;
											             end
											        2'd3:;
											    endcase
									        end
									  step6:begin
											    case(wr_cnt)
											        2'd0:begin
												            sda_o <= byte_r[3];       //sda数据改变
												            sclk_r     <= 1'b0;       //sclk线拉低
										             	 end
											        2'd1:begin
												            sclk_r     <= 1'b1;       //sclk线拉高，sda数据不变
											             end
										           2'd2:begin
												            sclk_r     <= 1'b0;       //sclk线拉低
												            wr_step <= step7;
											             end
											        2'd3:;
											    endcase
									        end
									  step7:begin
											    case(wr_cnt)
											        2'd0:begin
												            sda_o <= byte_r[2];       //sda数据改变
												            sclk_r     <= 1'b0;       //sclk线拉低
											             end
											        2'd1:begin
												            sclk_r     <= 1'b1;       //sclk线拉高，sda数据不变
											             end
											        2'd2:begin
												            sclk_r     <= 1'b0;       //sclk线拉低
												            wr_step <= step8;
											             end
										           2'd3:;
											    endcase
									        end
									  step8:begin
											    case(wr_cnt)
											        2'd0:begin
												            sda_o <= byte_r[1];       //sda数据改变
												            sclk_r     <= 1'b0;       //sclk线拉低
											             end
											        2'd1:begin
												            sclk_r     <= 1'b1;       //sclk线拉高，sda数据不变
											             end
											        2'd2:begin
												            sclk_r     <= 1'b0;       //sclk线拉低
												            wr_step <= step9;
											             end
											        2'd3:;
											    endcase
									        end
									  step9:begin
											    case(wr_cnt)
											        2'd0:begin
												            sda_o <= byte_r[0];       //sda数据改变
												            sclk_r     <= 1'b0;       //sclk线拉低
											             end
											        2'd1:begin
												            sclk_r     <= 1'b1;       //sclk线拉高，sda数据不变
											             end
											        2'd2:begin
												            sclk_r     <= 1'b0;       //sclk线拉低
												            wr_step <= step10;
											             end
											        2'd3:;
											    endcase
									        end
									  ///////////////////////////////////////////////////////////////////
									  step10:begin  //判断三个字节是否都写入完
											     case(wr_cnt)
											         2'd0:begin
												             sclk_r     <= 1'b0;      //sclk线拉低
												             iolink     <= 1'b0;      
											              end
											         2'd1:begin
												             sclk_r     <= 1'b1;      //sclk线拉高, 8bit数据传输完成后，给出第9个slk时钟脉冲，接收从机响应
											              end
											         2'd2:begin
												             sclk_r     <= 1'b0;      //sclk线拉低
																 if(sda == 1'b0 && byte_cnt < 2'd2)  //若从机响应（低电平）并且写入的字节数小于3则继续返回step1进行下一个字节的写入
																     begin
																	    iolink          <= 1'b1;
																	    wr_step         <= step2;
																	    byte_cnt        <= byte_cnt + 2'd1;
																	    case(byte_cnt)
																			  2'd0:byte_r <= idata_r[15:8];
																			  2'd1:byte_r <= idata_r[7:0];
																			  default:;
																	    endcase
																	  end
																 else                    //从机无ack，或者3个字节写入完毕则停止操作，返回wait_s状态
																	  begin
																	    byte_cnt   <= 2'd0;
																	    wr_step    <= step11;
																	  end
															  end
											         2'd3:;
											     endcase
											   end
									  ///////////////////////////////////////////////////////////////////
									  step11:begin//产生一个停止条件
		      								  case(wr_cnt)
												      2'd0:begin
															    sclk_r     <= 1'b0;//sclk线拉低
															    sda_o      <= 1'b0;
															    iolink     <= 1'b1;
														     end
														2'd1:begin
															    sda_o      <= 1'b0;
															    sclk_r     <= 1'b1;//sclk线拉高
														     end
														2'd2:begin
															    sda_o      <= 1'b1;//在sclk高电平时sda从低到高，则产生一个停止条件
															    sclk_r     <= 1'b1;//sclk线拉低
															    wr_done_r  <= 1'b1;//写操作完成,wr_done拉高标志写操作完成
															    state      <= wait_s;//写操作完成，返回等待状态
														     end
														2'd3:;
												  endcase
												end
									  default:;
                         endcase
                       end
/////////////////////////////////////////////////////////
	             rd_s:begin
	                    if(wr_cnt>=2'd2)//每3个iclk跳转一个步骤，每个步骤包含了1bit数据的传输
		                     begin
				                 wr_cnt <= 2'd0;
				               end
		                 else
		                     begin
				                 wr_cnt <= wr_cnt+2'd1;
				               end
		                 case(rd_step)
		                     step1:begin//产生一个开始条件
		                             case(wr_cnt)
				                           2'd0:sda_o   <= 1'b0;
				                           2'd1:;
				                           2'd2:rd_step <= step2;
				                           2'd3:;
				                       endcase
		                           end
									///////////////////////////////////////////////////////////////////
		                     step2:begin    //sclk连续产生8个时钟脉冲，用于sda输出8bit数据
											  case(wr_cnt)
													2'd0:begin
														    sda_o <= byte_r[7];//sda数据改变
														    sclk_r     <= 1'b0;//sclk线拉低
													     end
													2'd1:begin
														    sclk_r     <= 1'b1;//sclk线拉高
													     end
													2'd2:begin
														    sclk_r     <= 1'b0;//sclk线拉低
														    rd_step <= step3;
													     end
													2'd3:;
											  endcase
											end
									step3:begin
											  case(wr_cnt)
													2'd0:begin
														    sda_o <= byte_r[6];//sda数据改变
														    sclk_r     <= 1'b0;//sclk线拉低
													     end
													2'd1:begin
														    sclk_r     <= 1'b1;//sclk线拉高
													     end
													2'd2:begin
														    sclk_r     <= 1'b0;//sclk线拉低
														    rd_step <= step4;
													     end
													2'd3:;
											  endcase
											end
									step4:begin
											  case(wr_cnt)
													2'd0:begin
														    sda_o <= byte_r[5];//sda数据改变
														    sclk_r     <= 1'b0;//sclk线拉低
													     end
													2'd1:begin
														    sclk_r     <= 1'b1;//sclk线拉高
													     end
													2'd2:begin
														    sclk_r     <= 1'b0;//sclk线拉低
														    rd_step <= step5;
													     end
													2'd3:;
											  endcase
											end
									step5:begin
											  case(wr_cnt)
													2'd0:begin
														    sda_o <= byte_r[4];//sda数据改变
														    sclk_r     <= 1'b0;//sclk线拉低
													     end
													2'd1:begin
														    sclk_r     <= 1'b1;//sclk线拉高
													     end
													2'd2:begin
														    sclk_r     <= 1'b0;//sclk线拉低
														    rd_step <= step6;
													     end
													2'd3:;
											  endcase
											end
									step6:begin
											  case(wr_cnt)
													2'd0:begin
														    sda_o <= byte_r[3];//sda数据改变
														    sclk_r     <= 1'b0;//sclk线拉低
													     end
													2'd1:begin
														    sclk_r     <= 1'b1;//sclk线拉高
													     end
													2'd2:begin
														    sclk_r     <= 1'b0;//sclk线拉低
														    rd_step <= step7;
													     end
													2'd3:;
											  endcase
											end
									step7:begin
											  case(wr_cnt)
													2'd0:begin
														    sda_o <= byte_r[2];//sda数据改变
														    sclk_r     <= 1'b0;//sclk线拉低
													     end
													2'd1:begin
														    sclk_r     <= 1'b1;//sclk线拉高
													     end
													2'd2:begin
														    sclk_r     <= 1'b0;//sclk线拉低
														    rd_step <= step8;
													     end
													2'd3:;
											  endcase
											end
									step8:begin
											  case(wr_cnt)
													2'd0:begin
														    sda_o <= byte_r[1];//sda数据改变
														    sclk_r     <= 1'b0;//sclk线拉低
													     end
													2'd1:begin
														    sclk_r     <= 1'b1;//sclk线拉高
													     end
													2'd2:begin
														    sclk_r     <= 1'b0;//sclk线拉低
														    rd_step <= step9;
													     end
													2'd3:;
											  endcase
											end
									step9:begin
											  case(wr_cnt)
													2'd0:begin
														    sda_o <= byte_r[0];//sda数据改变
														    sclk_r     <= 1'b0;//sclk线拉低
													     end
													2'd1:begin
														    sclk_r     <= 1'b1;//sclk线拉高
													     end
													2'd2:begin
														    sclk_r     <= 1'b0;//sclk线拉低
														    rd_step <= step10;
													     end
													2'd3:;
											  endcase
											end
									///////////////////////////////////////////////////////////////////
									 step10:begin
										       case(wr_cnt)//判断前两个字节是否写入
											        2'd0:begin
												            sclk_r     <= 1'b0;//sclk线拉低
												            iolink     <= 1'b0;
											             end
											        2'd1:begin
												            sclk_r     <= 1'b1;//sclk线拉高  8bit数据传输完成后，给出第9个slk时钟脉冲，接收从机响应
											             end
											        2'd2:begin
												            sclk_r     <= 1'b0;//sclk线拉低
												            if(sda == 1'b0 && byte_cnt < 2'd1)//若从机响应并且写入的字节数小于2则继续返回step2进行下一个字节的写入,否则进入step11读出一字节数据
													             begin
													               iolink     <= 1'b1;
													               rd_step    <= step2;
													               byte_cnt   <= byte_cnt+2'd1;
													               case(byte_cnt)
													                   2'd0:byte_r <= idata_r[15:8];
													                   default:;
													               endcase
													             end
												            else 
																if(sda == 1'b0)    //前两个字节写入完毕，进入step11产生一个开始条件，进行读操作
													             begin
													               byte_cnt   <=2'd0;
													               rd_step      <= step11;
													             end
												            else 
																if(sda == 1'b1)    //无响应
													             begin
													               state <= wait_s;
													             end
											             end
											        2'd3:;
										       endcase
										     end
									///////////////////////////////////////////////////////////////////
									 step11:begin   //产生一个开始条件（允许无停止条件，可重复开始条件）
									          case(wr_cnt)
												     2'd0:begin
															   sclk_r     <= 1'b0;//sclk线拉低
															   sda_o      <= 1'b1;
															   iolink     <= 1'b1;
														    end
													  2'd1:begin
															   sda_o      <= 1'b1;
															   sclk_r     <= 1'b1;//sclk线拉高
														    end
													  2'd2:begin
															   sda_o      <= 1'b0;//在sclk高电平时sda从高到低，则产生一个开始条件
															   sclk_r     <= 1'b1;
															   byte_r     <= idata_r[23:16];
															   rd_step    <= step12;//开始读出1字节数据
														    end
													  2'd3:;
												 endcase
									        end
									///////////////////////////////////////////////////////////////////
									  step12:begin //写需要读取的寄存器地址
											     case(wr_cnt)
											         2'd0:begin
												             sda_o  <= byte_r[7];//sda在sclk低电平时数据改变
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_step <= step13;
											              end
											         2'd3:;
											     endcase
									         end
									  step13:begin
											     case(wr_cnt)
											         2'd0:begin
												             sda_o  <= byte_r[6];//sda在sclk低电平时数据改变
												             sclk_r <= 1'b0;//sclk线拉低
											              end
														2'd1:begin
															    sclk_r <= 1'b1;//sclk线拉高
														     end
														2'd2:begin
															    sclk_r <= 1'b0;//sclk线拉低
															    rd_step <= step14;
														     end
														2'd3:;
											     endcase
									         end
									  step14:begin
											     case(wr_cnt)
											         2'd0:begin
												             sda_o  <= byte_r[5];//sda在sclk低电平时数据改变
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_step <= step15;
											              end
											         2'd3:;
											     endcase
									         end
									  step15:begin
												  case(wr_cnt)
	   												2'd0:begin
		 													    sda_o  <= byte_r[4];//sda在sclk低电平时数据改变
														       sclk_r <= 1'b0;//sclk线拉低
															  end
														2'd1:begin
																 sclk_r <= 1'b1;//sclk线拉高
															  end
														2'd2:begin
																 sclk_r <= 1'b0;//sclk线拉低
																 rd_step <= step16;
															  end
														2'd3:;
											     endcase
									         end
									  step16:begin
											     case(wr_cnt)
											         2'd0:begin
												             sda_o  <= byte_r[3];//sda在sclk低电平时数据改变
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_step <= step17;
											              end
											         2'd3:;
											     endcase
									         end
									  step17:begin
											     case(wr_cnt)
											         2'd0:begin
												             sda_o  <= byte_r[2];//sda在sclk低电平时数据改变
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_step <= step18;
											              end
											         2'd3:;
											     endcase
									         end
									  step18:begin
											     case(wr_cnt)
											         2'd0:begin
												             sda_o  <= byte_r[1];//sda在sclk低电平时数据改变
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_step <= step19;
											              end
											         2'd3:;
											     endcase
									         end
									  step19:begin
											     case(wr_cnt)
											         2'd0:begin
												             sda_o  <= 1'b1;//sda在sclk低电平时数据改变,此位为高表示I2C为读操作
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             iolink <= 1'b0;
												             rd_step <= step20;
											              end
											         2'd3:;
											     endcase
									         end
									///////////////////////////////////////////////////////////////////
									  step20:begin
											     case(wr_cnt)
											         2'd0:begin
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             if(sda == 1'b0)//接收响应
													              begin
													                rd_step <= step21;
													              end
												             else
													              begin
													                state <= wait_s;
													              end
												           end
											         2'd3:;
											     endcase
									         end
									///////////////////////////////////////////////////////////////////
									  step21:begin   //读sda数据
											     case(wr_cnt)
											         2'd0:begin
												             iolink <= 1'b0;//表示读sda数据
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_byte[7] <= sda;
												             rd_step <= step22;
											              end
											         2'd3:;
											     endcase
									         end
									  step22:begin
											     case(wr_cnt)
											         2'd0:begin
												             iolink <= 1'b0;//表示读sda数据
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_byte[6] <= sda;
												             rd_step <= step23;
											              end
											         2'd3:;
											     endcase
									         end
									  step23:begin
											     case(wr_cnt)
											         2'd0:begin
												             iolink <= 1'b0;//表示读sda数据
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_byte[5] <= sda;
												             rd_step <= step24;
											              end
											         2'd3:;
											     endcase
									         end
									  step24:begin
											     case(wr_cnt)
											         2'd0:begin
												             iolink <= 1'b0;//表示读sda数据
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_byte[4] <= sda;
												             rd_step <= step25;
											              end
											         2'd3:;
											     endcase
									         end
									  step25:begin
											     case(wr_cnt)
											         2'd0:begin
												             iolink <= 1'b0;//表示读sda数据
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_byte[3] <= sda;
												             rd_step <= step26;
											              end
											         2'd3:;
											     endcase
									         end
									  step26:begin
											     case(wr_cnt)
											         2'd0:begin
												             iolink <= 1'b0;//表示读sda数据
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_byte[2] <= sda;
												             rd_step <= step27;
											              end
											         2'd3:;
											     endcase
									         end
									  step27:begin
											     case(wr_cnt)
											         2'd0:begin
												             iolink <= 1'b0;//表示读sda数据
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_byte[1] <= sda;
												             rd_step <= step28;
											              end
											         2'd3:;
											     endcase
									         end
									  step28:begin
											     case(wr_cnt)
											         2'd0:begin
												             iolink <= 1'b0;//表示读sda数据
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_byte[0] <= sda;
												             iolink <= 1'b1;//表示写sda数据
												             rd_step <= step29;
											              end
											         2'd3:;
											     endcase
									         end
									  step29:begin
											     case(wr_cnt)
											         2'd0:begin
												             sda_o <= 1'b1;
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sda_o <= 1'b1;
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
												             sda_o <= 1'b1;
												             sclk_r <= 1'b0;//sclk线拉低
												             rd_step <= step30;
											              end
											         2'd3:;
											     endcase
									         end
									  step30:begin
											     case(wr_cnt)
											         2'd0:begin
												             sda_o <= 1'b0;
												             sclk_r <= 1'b0;//sclk线拉低
											              end
											         2'd1:begin
												             sda_o <= 1'b0;
												             sclk_r <= 1'b1;//sclk线拉高
											              end
											         2'd2:begin
																 sda_o <= 1'b1;
																 sclk_r <= 1'b1;//sclk线拉低
																 rd_data_r <= rd_byte;//将寄存的串转并数据输出到输出端口
																 rd_done_r <= 1'b1;//读操作完成后，rd_done拉高表示读操作完成
																 rd_data_en_r <= 1'b1;//读数据有效标志拉高，表明此时输出端口上的数据有效
																 state    <= wait_s;
											              end
											         2'd3:;
											     endcase
									         end
									  default:;
		                 endcase
	                  end
	             default:;
            endcase
          end
  end
endmodule 